﻿using Datos.Interfaces;
using Entidad;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Data;
using DapperExtensions;
using Dapper;
using System.Data;
using Entidad.Criterios;

namespace Datos.Repositories
{
    public class MarcaRepository : IMarcaRepository
    {

        private readonly Microsoft.Practices.EnterpriseLibrary.Data.Database _db;

        static MarcaRepository()
        {
            //DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory(), false);
        }

        public MarcaRepository()
        {
            _db = DatabaseFactory.CreateDatabase("RealConnection");
        }

        public IList<Marca> FindAll()
        {
            using(IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"SELECT * FROM Marca m
                                        JOIN Proveedor p ON p.Id = m.IdProveedor
                                        JOIN Estado e ON e.Id = m.IdEstado";

                var datos = conn.Query<Marca, Proveedor, Estado, Marca>(query, (marca, proveedor, estado) =>
                    {
                        marca.Proveedor = proveedor;
                        marca.Estado = estado;
                        return marca;
                    });

                return datos.ToList();
            }
        }

        public IQueryable<Marca> Find(Expression<Func<Marca, bool>> predicate)
        {
            throw new NotImplementedException();
        }

        public Marca FindById(int id)
        {
            Marca marca;
            using(IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"SELECT * FROM Marca m
                                        JOIN Proveedor p ON p.Id = m.IdProveedor
                                        JOIN Estado e ON e.Id = m.IdEstado
                                        WHERE m.Id = @id";

                marca = conn.Query<Marca, Proveedor, Estado, Marca>(query, (mar, proveedor, estado) =>
                {
                    mar.Proveedor = proveedor;
                    mar.Estado = estado;

                    return mar;

                }, new { id = id }).SingleOrDefault();
               
            }

            return marca;
        }

        public int Add(Marca newEntity)
        {
            using (IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"INSERT INTO Marca (
                                    Denominacion,
                                    IdProveedor,
                                    IdEstado) VALUES(
                                    @denominacion, @idproveedor, @idestado)";

                return conn.Execute(query, new
                {
                    denominacion = newEntity.Denominacion,
                    idproveedor = newEntity.Proveedor.Id,
                    idestado = newEntity.Estado.Id,
                });
            }
        }

        public bool Remove(int id)
        {
            bool resultado = false;
            using (IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"UPDATE Marca SET IdEstado = 2
                                        WHERE Id = @id";

                int filasAfectadas = conn.Execute(query, new
                {
                    id = id,
                });

                if (filasAfectadas > 0)
                    resultado = true;
            }

            return resultado;
        }

        public int Modify(Marca entity)
        {
            using(IDbConnection conn = _db.CreateConnection())
            {
                string query = @"UPDATE Marca SET Denominacion = @denominacion,
                                 IdProveedor = @idproveedor, IdEstado = @idestado
                                 WHERE Id = @id";

                return conn.Execute(query, new
                {
                    denominacion = entity.Denominacion,
                    idproveedor = entity.Proveedor.Id,
                    idestado = entity.Estado.Id,
                    id = entity.Id,

                });
            }
        }


        public IList<Marca> FindByCriteria(MarcaCriteria filtro)
        {
            if (String.IsNullOrEmpty(filtro.Denominacion))
                filtro.Denominacion = DBNull.Value.ToString();

            using(IDbConnection conn = _db.CreateConnection())
            {
                string query = @"SELECT * FROM Marca m
                                        JOIN Proveedor p ON p.Id = m.IdProveedor
                                        JOIN Estado e ON e.Id = m.IdEstado
                                        WHERE ((m.Denominacion IS NULL) OR (m.Denominacion LIKE '%" + filtro.Denominacion + "%')) " +
                                        "AND ((m.IdProveedor IS NULL) OR (m.IdProveedor = @idproveedor))";

                var datos = conn.Query<Marca, Proveedor, Estado, Marca>(query, (mar, proveedor, estado) =>
                    {
                        mar.Proveedor = proveedor;
                        mar.Estado = estado;
                        return mar;
                    }, new { 

                        idproveedor = filtro.IdProveedor,                 
                    });

                return datos.ToList();
            }
          
        }

    }
}
